#include <stdio.h>
#include <process.h>
#include "../inc/Hook.h"





static HHOOK theHook;
static BOOL hooked=FALSE;
static HINSTANCE hInstDLL; 


void ErrorExit(LPTSTR lpszFunction) ;


DllExport int enableHook()
{



	if(hooked)return ERR_HOOK;
	

	if(hInstDLL==NULL)
	{
		ErrorExit("Load Library");
	}
    

    theHook=SetWindowsHookEx(WH_KEYBOARD, 
                           (HOOKPROC)KeyboardProc, 
                            /*(HINSTANCE) NULL*/hInstDLL, /**GetCurrentThreadId()*/0); 





	
	if(theHook)
	{
		hooked=TRUE;
		//hookLog("enabled Hook,threadID=%4d\n",GetCurrentThreadId());
    	return HOOKED;
	}
	else
	{
		ErrorExit("Set Hook");
	}



	return ERR_HOOK;
		//InstallHook(TRUE);
	//	return HOOKED;
}
DllExport int disableHook()
{

	if(!hooked)return ERR_HOOK;

    UnhookWindowsHookEx(theHook); 
	hooked=FALSE;
	//EndHook();
	return UN_HOOK;

}

 

void hookLog(const char* format,...)
{

	va_list tag;
	
	FILE* fp=fopen(LOG_FILE,"a");
    va_start (tag, format);
    
	vfprintf(fp,format,tag);
	va_end (tag);
	fclose(fp);
}

DllExport LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{




	 if (nCode >=0&&nCode!=HC_NOREMOVE)
	 {

           
		    HANDLE mailslot=CreateFile(EVT_CHANNEL_NAME,
			GENERIC_WRITE, FILE_SHARE_READ,
			(LPSECURITY_ATTRIBUTES) NULL,
			OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
			(HANDLE) NULL);
			if (mailslot == INVALID_HANDLE_VALUE)
			{
				hookLog( "ERROR(Client): Unable to create a mailslot.\n");
				
			}
			else
			{

					unsigned char buf[4];
					DWORD NumBytesWritten;
					buf[0]=0;
					buf[1]=(wParam&0xff00)>>8;
					buf[2]=wParam&0xff;
					buf[3]=1;//down
					if(lParam&0x80000000)
					{
						buf[3]=0;
					}
					if (!WriteFile(mailslot,
						buf, sizeof(buf),
						&NumBytesWritten, (LPOVERLAPPED) NULL))
					{
						hookLog("write evt err!!!!\n");

					}
					CloseHandle(mailslot);



			}
		
		
	


	 }

	  
      
	  return CallNextHookEx(theHook, nCode, 
            wParam, lParam); 

}




void ErrorExit(LPTSTR lpszFunction) 
{ 
    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;

    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); 
    wsprintf((LPTSTR)lpDisplayBuf, 
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(dw); 
}

BOOL WINAPI DllMain(HINSTANCE hInstance,ULONG What,LPVOID NotUsed)
{

	
	switch(What)
	{
		case DLL_PROCESS_ATTACH:
			//hookLog("dllmain,threadID=%4d\n",GetCurrentThreadId());
			hInstDLL = hInstance;
			break;
		case DLL_PROCESS_DETACH:
			break;
		case DLL_THREAD_ATTACH:
			break;
		case DLL_THREAD_DETACH:
			break;

	}
	return 1;
}
